package controllers

import (
	"GoWeb_Advanced/00_bluebell/logic"
	"GoWeb_Advanced/00_bluebell/models"
	"strconv"

	"go.uber.org/zap"

	"github.com/gin-gonic/gin"
)

// CreatePostHandler 创建帖子的处理函数
func CreatePostHandler(ctx *gin.Context) {
	//1.获取参数及参数的校验
	//ctx.ShouldBindJSON() //validator ——> binding tag
	p := new(models.Post)
	if err := ctx.ShouldBindJSON(p); err != nil {
		zap.L().Debug("ctx.ShouldBindJSON(p) error", zap.Any("err", err))
		zap.L().Error("create post with invalid param")
		ResponseErrorWithMsg(ctx, CodeInvalidParam, err.Error())
		return
	}
	//参数校验

	//从 ctx 取到当前发请求的用户的 ID
	userID, err := GetCurrentUserID(ctx)
	if err != nil {
		zap.L().Error("GetCurrentUserID() failed", zap.Error(err))
		ResponseError(ctx, CodeNeedLogin)
	}
	p.AuthorID = userID

	//2.创建帖子
	if err = logic.CreatePost(p); err != nil {
		zap.L().Error("logic.CreatePost() failed", zap.Error(err))
		ResponseError(ctx, CodeServerBusy) //不要将服务端的错误暴露到外面
		return
	}

	//3.返回响应
	ResponseSuccess(ctx, nil)
}

// GetPostDetailHandler 获取帖子详情的处理函数
func GetPostDetailHandler(ctx *gin.Context) {
	//1.获取参数（从 URL 中获取帖子的 ID）
	pidStr := ctx.Param("id")
	pid, err := strconv.ParseInt(pidStr, 10, 64)
	if err != nil {
		zap.L().Error("get post detail with invalid param", zap.Error(err))
		ResponseError(ctx, CodeInvalidParam)
		return
	}
	//2.根据 ID 取出帖子数据（数据库）
	data, err := logic.GetPostByID(pid)
	if err != nil {
		zap.L().Error("logic.GetPostByID(pid) failed", zap.Error(err))
		ResponseError(ctx, CodeServerBusy)
		return
	}
	//3.返回响应
	ResponseSuccess(ctx, data)
}

// GetPostListHandler 获取贴子列表的处理函数
// @Summary 获取贴子列表的处理函数（摘要）
// @Description 查询贴子列表（描述）
// @Tags 贴子相关接口（标签，能够给接口分个组）
// @Accept application/json (接收请求的内容编码类型)
// @Produce application/json (返回的响应数据的编码类型)
// @Param Authorization header string false "Bearer 用户令牌"
// @param object query models.ParamPostList false "查询参数"
// @Security ApiKeyAuth
// @Success 200 {object} _ResponsePostList
// @Router /post [get]
func GetPostListHandler(ctx *gin.Context) {
	//获取分页参数
	page, size := GetPageInfo(ctx)
	//获取数据
	data, err := logic.GetPostList(page, size)
	if err != nil {
		zap.L().Error("logic.GetPostList() failed", zap.Error(err))
		ResponseError(ctx, CodeServerBusy)
		return
	}
	//返回响应
	ResponseSuccess(ctx, data)
}

// GetPostListHandler2 升级版帖子列表接口
// @Summary 升级版帖子列表接口
// @Description 可按社区按时间或分数排序查询帖子列表接口
// @Tags 帖子相关接口
// @Accept application/json
// @Produce application/json
// @Param Authorization header string false "Bearer 用户令牌"
// @Param object query models.ParamPostList false "查询参数"
// @Security ApiKeyAuth
// @Success 200 {object} _ResponsePostList
// @Router /posts2 [get]
func GetPostListHandler2(ctx *gin.Context) {
	// GetPostListHandler2 升级版帖子列表接口
	// 跟据前端传来的参数动态地去获取帖子列表
	// 按创建时间 或者 按照分数 排序
	// 1.获取请求的 query string 参数
	// 2.去 redis 查询 id 值
	// 3.根据 id 去数据库查询帖子详细信息

	//GET 请求参数(query string)：/api/v1/posts2?page=1&size=10&order=time
	//创建结构体时指定初始参数
	p := &models.ParamPostList{
		Page:  1,
		Size:  10,
		Order: models.OrderTime, //默认按照时间排序
	}
	//ctx.ShouldBind() 跟据请求的数据类型选择相应的方法去获取数据
	//ctx.ShouldBindJSON() 如果请求中携带的是 json 格式的数据，才能用这个方法获取到数据
	if err := ctx.ShouldBindQuery(p); err != nil {
		zap.L().Error("GetPostListHandler2 with invalid params", zap.Error(err))
		ResponseError(ctx, CodeInvalidParam)
		return
	}

	//获取数据
	data, err := logic.GetPostListNew(p) //更新：合二为一
	if err != nil {
		zap.L().Error("logic.GetPostList2() failed", zap.Error(err))
		ResponseError(ctx, CodeServerBusy)
		return
	}
	//返回响应
	ResponseSuccess(ctx, data)
}

//
//// GetCommunityPostListHandler 根据社区去查询帖子列表
//func GetCommunityPostListHandler(ctx *gin.Context) {
//	//创建结构体时指定初始参数
//	p := &models.ParamCommunityPostList{
//		ParamPostList: &models.ParamPostList{
//			Page:  1,
//			Size:  10,
//			Order: models.OrderTime, //默认按照时间排序
//		},
//	}
//	//ctx.ShouldBind() 跟据请求的数据类型选择相应的方法去获取数据
//	//ctx.ShouldBindJSON() 如果请求中携带的是 json 格式的数据，才能用这个方法获取到数据
//	if err := ctx.ShouldBindQuery(p); err != nil {
//		zap.L().Error("GetPostListHandler2 with invalid params", zap.Error(err))
//		ResponseError(ctx, CodeInvalidParam)
//		return
//	}
//	//获取数据
//	data, err := logic.GetCommunityPostList(p)
//	if err != nil {
//		zap.L().Error("logic.GetPostList2() failed", zap.Error(err))
//		ResponseError(ctx, CodeServerBusy)
//		return
//	}
//	//返回响应
//	ResponseSuccess(ctx, data)
//}
